package com.gitee.wsl.platform.concurrent

import kotlinx.coroutines.CloseableCoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext


internal expect class InternalThreadId


internal expect class InternalThread {
    companion object {
        fun getId(): InternalThreadId
        fun sleepMs(millis: Int)
    }
}

/**
 * Runs the provided [block] on the main thread
 * @param block the code to run on the main thread.
 */
@Suppress("KotlinAmbiguousActuals")
expect fun runOnMain(block: () -> Unit)

expect fun<T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T) : T


/**
 * Creates a coroutine execution context using a single thread.
 *
 * **NOTE: The resulting [CloseableCoroutineDispatcher] owns native resources (its thread).
 * Resources are reclaimed by [CloseableCoroutineDispatcher.close].**
 * @param name The name of the thread to be created.
 */
@OptIn(ExperimentalCoroutinesApi::class)
expect fun singleThreadDispatcher(name: String): CloseableCoroutineDispatcher

/**
 * Creates a coroutine execution context using a thread pool.
 *
 * **NOTE: The resulting [CloseableCoroutineDispatcher] owns native resources (its thread).
 * Resources are reclaimed by [CloseableCoroutineDispatcher.close].**
 * @param numberOfThreads The number of the threads that the thread pool should consist of.
 * @param name The name of the thread pool to be created.
 */
@OptIn(ExperimentalCoroutinesApi::class)
expect fun threadPoolDispatcher(numberOfThreads: UInt, name: String): CloseableCoroutineDispatcher


@OptIn(ExperimentalCoroutinesApi::class)
fun Dispatchers.singleDispatcher(name: String) = singleThreadDispatcher(name)

@OptIn(ExperimentalCoroutinesApi::class)
fun Dispatchers.poolDispatcher(numberOfThreads: UInt, name: String) = threadPoolDispatcher(numberOfThreads, name)
